package fr.cie.blog.modeldao.services;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import org.apache.log4j.Logger;

/**
 * "Tool class" on singleton pattern to close resulset, connection and
 * preparestatement.
 * 
 * La classe est final, car un singleton n'est pas censé avoir d'héritier. En
 * effet, en Java il n'y a pas de polymorphisme sur les méthodes static, il est
 * donc préférable de verrouiller la classe.
 * 
 * @author Jee3
 */
public final class GestionBaseDeDonnees {

	/**
	 * Log4J the logger.
	 */
	private static final Logger LOG = Logger
			.getLogger(GestionBaseDeDonnees.class);

	// L'utilisation du mot clé volatile permet, en Java version 5 et supérieur,
	// d'éviter le cas où "Singleton.instance" est non-nul, mais pas encore
	// "réellement" instancié. De Java version 1.2 à 1.4, il est possible
	// d'utiliser la classe ThreadLocal.
	/**
	 * instance.
	 */
	private static GestionBaseDeDonnees instance = null;

	/**
	 * Default PRIVATE constructor.
	 */
	private GestionBaseDeDonnees() {
		super();
	}

	/**
	 * Method to get singleton Instance.
	 * 
	 * @return singleton instance.
	 */
	public static synchronized GestionBaseDeDonnees getInstance() {
		// Le "Double-Checked Singleton"/"Singleton doublement vérifié" permet
		// d'éviter un appel coûteux à synchronized,
		// une fois que l'instanciation est faite.
		if (GestionBaseDeDonnees.instance == null) {
			// Le mot-clé synchronized sur ce bloc empêche toute instanciation
			// multiple même par différents "threads".
			// Il est TRES important.
			// synchronized (GestionBaseDeDonnees.class) {
			// if (GestionBaseDeDonnees.instance == null) {
			GestionBaseDeDonnees.instance = new GestionBaseDeDonnees();
			// }
			// }
		}
		return GestionBaseDeDonnees.instance;
	}

	/**
	 * Close the Connection.
	 * 
	 * @param connection
	 *            the connection
	 */
	public void closeConnection(final Connection connection) {
		if (connection != null) {
			try {
				connection.close();
			} catch (final Exception e) {
				LOG.debug("Erreur lors de la fermerture d'une connexion");
			}
		}
	}

	/**
	 * Close the request.
	 * 
	 * @param request
	 *            the Statement to close
	 */
	public void closeRequest(final Statement request) {
		if (request != null) {
			try {
				request.close();
			} catch (final Exception e) {
				LOG.debug("Erreur lors de la fermerture d'une requête");
			}
		}
	}

	/**
	 * Close the ResultSet.
	 * 
	 * @param resultSet
	 *            the ResultSet to close
	 */
	public void closeResulset(final ResultSet resultSet) {
		if (resultSet != null) {
			try {
				resultSet.close();
			} catch (final Exception e) {
				LOG.debug("Erreur lors de la fermerture d'une"
						+ " connexion d'un resultset");
			}
		}
	}

}
